﻿/*
 * Application runtime
 *
 * Command line arguments:
 *
 *  --help       list all command and exit
 *  --debug      show debug console
 *
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Snowdreamist.ComponentModel.MEF;
using Snowdreamist.ComponentModel.Plugin;
using Snowdreamist.Runtime;
using Snowdreamist.Runtime.Services;
using Snowdreamist.Windows.Data;

namespace SNSpirit.Application
{
    public sealed class ApplicationRuntime
    {
        /// <summary>
        /// runtime
        /// </summary>
        public static ApplicationRuntime Current { get; private set; }

        /// <summary>
        /// ctor
        /// </summary>
        public ApplicationRuntime(Bootstrapper bootStrapper)
        {
            if (bootStrapper == null)
                throw new ArgumentNullException("bootStrapper");

            lock (this)
            {
                if (Current != null)
                    throw new InvalidOperationException("ApplicationRuntime has already created");

                // set current
                Current = this;
                this._bootStrapper = bootStrapper;
                // init
                this.Shell = new GlobalShell();
            }
        }

        /// <summary>
        /// Run application
        /// </summary>
        /// <param name="args"></param>
        /// <returns>True for run and False for close</returns>
        public bool Run(string[] args)
        {
            // init
            this.RuntimeConfiguration = new RuntimeConfiguration();
            // parse arguments
            if (args != null && args.Count() != 0)
                this.ParseArguments(args);
            // check config
            if (this.RuntimeConfiguration.IsCloseBeforeBoot)
            {
                // close
                return false;
            }
            else
            {
                // load language
                LanguageManager.Current.LoadLanguageResources(System.Windows.Application.Current.Resources["Languages"] as LanguageResources);
                // boot
                this._bootStrapper.Run();
                // run system runtime
                this.RegisterRuntimeSerivces();
                // handle configuration
                this.HandleConfiguration();
                // return
                return true;
            }
        }

        /// <summary>
        /// Runtime configuration
        /// </summary>
        public RuntimeConfiguration RuntimeConfiguration { get; private set; }

        /// <summary>
        /// Global Shell
        /// </summary>
        public GlobalShell Shell { get; private set; }

        /// <summary>
        /// Boot strapper
        /// </summary>
        private Bootstrapper _bootStrapper;

        private void ParseArguments(string[] args)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                    case "--help":
                        // print all commands
                        this.RuntimeConfiguration.IsCloseBeforeBoot = true;

                        Console.Write("--help\t\tShow help and exit\n" +
                            "--version\t\tShow version and exit\n" +
                            "--debug\t\tShow Debug Console\n");

                        break;

                    case "--version":
                        // show version
                        this.RuntimeConfiguration.IsCloseBeforeBoot = true;

                        Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Version.ToString());

                        break;

                    case "--debug":
                        // show debug console
                        this.RuntimeConfiguration.IsEnableDebugConsole = true;

                        break;

                    default:
                        // unknown command, exit
                        this.RuntimeConfiguration.IsCloseBeforeBoot = true;
                        Console.WriteLine("Unknown command " + args[i] + ", exit");
                        break;
                }
            }
        }

        private void HandleConfiguration()
        {
            // debug
            if (this.RuntimeConfiguration.IsEnableDebugConsole)
            {
                // load debug module
                SystemRuntime.Current.LoadModule("DebugModule");
            }
            // language
        }

        private void RegisterRuntimeSerivces()
        {
            // register
            SystemRuntime.Current.SetService<IComposition>(new MEFCompositionService(this._bootStrapper.GetExportProvider()));
            SystemRuntime.Current.SetService<IImportedPluginManager>(new MEFImportPluginManager(this._bootStrapper.GetExportProvider()));
        }
    }
}